package dao

import (
	"fmt"
	"gorm.io/gorm"
	"log"
	"strings"
	"time"
	"yundian/internel/app/helper"
	"yundian/internel/app/helper/request"
	"yundian/internel/app/helper/resphelper/placeresp"
	"yundian/internel/app/models/devices"
	"yundian/internel/app/models/placemodel"
	"yundian/internel/app/models/regions"
	"yundian/internel/app/models/users"
	"yundian/internel/pkg/dingo"
	"yundian/internel/pkg/dingo/global"
	"yundian/internel/pkg/utils"
	"yundian/internel/pkg/wechatpay"
)

// -------------------- dao层 - 网点相关操作 -----------------------//

type PlaceDao struct {
}

func NewPlaceDao() *PlaceDao {
	return &PlaceDao{}
}

// GetNearbyWifiList 查询附近门店WIFI
func (d *PlaceDao) GetNearbyWifiList(param *request.GetNearbyWifiListReq) *dingo.ErrorWrap {
	var lst []*request.GetNearbyWifiListRes

	sql := fmt.Sprintf(`FROM (SELECT r.id,p.id,place_name,r.wifi_name,r.wifi_password ROUND(6378.137 * 2 * ASIN 
	(SQRT(POW(SIN((%f * PI() / 180 - p.latitude * PI() / 180) / 2), 2) + COS(%f * PI() / 180) * COS
	(p.latitude * PI() / 180) * POW(SIN((%f * PI() / 180 - p.longitude * PI() / 180) / 2),2))),2) 
	distance FROM places p WHERE p.latitude<>'' ORDER BY distance) p2 LEFT JOIN room r ON p2.id=r.place_id 
	WHERE r.wifi_name<>'' p2.distance < 20`, param.Latitude, param.Latitude, param.Longitude)
	sqlLimit := `SELECT * ` + sql + fmt.Sprintf(` LIMIT %d`, 200)
	db := global.Orm.Raw(sqlLimit).Find(&lst)

	return dingo.ErrorIf(db.Error, lst)
}

func (d *PlaceDao) GetBrandConfigList(param *request.GetBrandConfigListReq) *dingo.ErrorWrap {
	var (
		lst    []*request.GetBrandConfigListRes
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)

	fields := `bc.*,kp.ka_name project_name`
	db := global.Orm.Table("brand_config bc").Select(fields)
	db.Joins("LEFT JOIN ka_project kp ON kp.ka_label=bc.project_key")

	if param.BrandId > 0 {
		db.Where("bc.id = ?", param.BrandId)
	}
	if param.BrandName != "" {
		db.Where("bc.brand_name LIKE ?", "%"+param.BrandName+"%")
	}

	db.Order("bc.id DESC")
	db.Limit(limit).Offset(offset).Find(&lst).Offset(-1).Limit(-1).Count(&count)
	return dingo.ErrorIf(db.Error, lst, count)
}

func (d *PlaceDao) GetBrandRelevancyConfigList(param *request.GetBrandRelevancyConfigListReq) *dingo.ErrorWrap {
	var (
		lst    []*request.GetBrandRelevancyConfigListRes
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)

	fields := `pbrc.*,p.place_name,bc.brand_name,kp.ka_name project_name,DATE_FORMAT
	(pbrc.create_time,'%Y-%m-%d %T')create_time,DATE_FORMAT(pbrc.update_time,'%Y-%m-%d %T')update_time`
	db := global.Orm.Table("place_brand_relevancy_config pbrc").Select(fields)
	db.Joins("LEFT JOIN places p ON p.id=pbrc.place_id")
	db.Joins("LEFT JOIN brand_config bc ON bc.id=pbrc.brand_id")
	db.Joins("LEFT JOIN ka_project kp ON kp.ka_label=pbrc.project_key")

	if !helper.IsAdminAndStaff(param.IsAdmin, param.ParentId) {
		uList := NewUserDao().QueryChildUserIds(param.LoginUserId).Unwrap().([]int)
		pList := NewUserDao().GetPlacesIds(param.LoginUserId, uList).Unwrap().([]int)
		db.Where("p.id IN ?", pList)
	}

	if param.PlaceId > 0 {
		db.Where("pbrc.place_id=?", param.PlaceId)
	}
	if param.BrandId > 0 {
		db.Where("pbrc.brand_id = ?", param.BrandId)
	}
	if param.BrandName != "" {
		db.Where("bc.brand_Name LIKE ?", "%"+param.BrandName+"%")
	}

	db.Order("pbrc.id DESC")
	db.Limit(limit).Offset(offset).Find(&lst).Offset(-1).Limit(-1).Count(&count)
	return dingo.ErrorIf(db.Error, lst, count)
}

func (d *PlaceDao) InsertBrandRelevancyConfig(param *placemodel.PlaceBrandRelevancyConfigDb) *dingo.ErrorWrap {
	db := global.Orm.Create(&param)
	return dingo.ErrorIf(db.Error)
}

func (d *PlaceDao) UpdateBrandRelevancyConfig(param *placemodel.PlaceBrandRelevancyConfigDb) *dingo.ErrorWrap {
	db := global.Orm.Where("id=?", param.Id).Updates(&param)
	return dingo.ErrorIf(db.Error)
}

func (d *PlaceDao) DeleteBrandRelevancyConfig(param *placemodel.PlaceBrandRelevancyConfigDb) *dingo.ErrorWrap {
	db := global.Orm.Model(&param).Delete("id", param.Id)
	return dingo.ErrorIf(db.Error)
}

func (d *PlaceDao) GetPlaceNearbyList(param *request.GetPlaceNearbyListReq) *dingo.ErrorWrap {
	var (
		lst    []*request.GetPlaceNearbyListRes
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)

	sql := fmt.Sprintf(`FROM (SELECT p.id,place_name,ltr.full_name area,ltr.lat latitude,ltr.lng longitude,
	ROUND(6378.137 * 2 * ASIN (SQRT(POW(SIN((%f * PI() / 180 - ltr.lat * PI() / 180) / 2), 2) + COS(%f * PI() / 180) * COS
	(ltr.lat * PI() / 180) * POW(SIN((%f * PI() / 180 - ltr.lng * PI() / 180) / 2),2))),2) distance FROM places p LEFT JOIN 
	lc_tencent_regions ltr ON p.county_id=ltr.id WHERE p.county_id>0 ORDER BY distance) p2  WHERE p2.distance < 50`,
		param.Latitude, param.Latitude, param.Longitude)
	sqlLimit := `SELECT * ` + sql + fmt.Sprintf(` LIMIT %d OFFSET %d`, limit, offset)
	db := global.Orm.Raw(sqlLimit).Find(&lst)

	global.Orm.Raw(`SELECT COUNT(1) ` + sql).Find(&count)

	return dingo.ErrorIf(db.Error, lst, count)
}

func (d *PlaceDao) GetPlaceInfoByDeviceSnANDid(deviceSn string, placeId int) *dingo.ErrorWrap {
	m := &devices.DeviceANDIdWithPlaceInfo{}
	db := global.Orm.Debug().Table("places p").Select("p.*,d.room")
	db.Joins("LEFT JOIN devices d ON p.id=d.place_id")
	db.Where("d.place_id=? AND d.device_sn=?", placeId, deviceSn).Find(&m)
	return dingo.ErrorIf(db.Error, m)
}

func (d *PlaceDao) SetStewardPlaceInformationConfig(param *request.StewardPlaceInformationConfigReq) *dingo.ErrorWrap {
	sql := `INSERT INTO places_information_config (place_id, type, status, config) VALUE (?,?,?,?) 
	ON DUPLICATE KEY UPDATE status=VALUES(status),config=VALUES(config)`
	for _, item := range param.List {
		if db := global.Orm.Exec(sql, item.PlaceId, item.Type, item.Status, item.Config); db.Error != nil {
			return dingo.ErrorIf(db.Error)
		}
	}
	return dingo.ErrorIf(nil)
}

func (d *PlaceDao) SetStewardPlace(param *request.SetStewardPlaceReq) *dingo.ErrorWrap {
	db := global.Orm.Table("places").Where("id=?", param.PlaceId).Updates(map[string]interface{}{
		"is_steward":   param.IsSteward,
		"place_name":   param.PlaceName,
		"service_call": param.ServiceCall,
	})
	return dingo.ErrorIf(db.Error)
}

func (d *PlaceDao) UpdatePlaceServiceStatus(id, status int) *dingo.ErrorWrap {
	db := global.Orm.Debug().Exec("update places set is_steward = ? where id = ?", status, id)
	return dingo.ErrorIf(db.Error, true)
}

// 获取门店状态
func (d *PlaceDao) GetPlaceStatusByPlaceId(id int) *dingo.ErrorWrap {
	placeStatus := &placeresp.GetPlaceStatusRes{}
	db := global.Orm.Table("places").
		Select("id as place_id, place_name, status,create_at,place_desc")
	db.Where("id = ?", id)
	db.Find(placeStatus)
	return dingo.ErrorIf(db.Error, placeStatus)
}

// GetStewardInformationConfig 消息配置查询
func (d *PlaceDao) GetStewardInformationConfig(placeIds []int) *dingo.ErrorWrap {
	var list []*placemodel.PlacesInformationConfig
	db := global.Orm.Table("places_information_config pic").Where("place_id IN (?)", placeIds)
	db.Find(&list)
	return dingo.ErrorIf(db.Error, list)
}

func (d *PlaceDao) GetStewardSearchPlaceList(param *request.GetStewardPlaceListReq) *dingo.ErrorWrap {
	var (
		lst    []*request.GetStewardSearchPlaceListRes
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)

	fields := `p.id,p.user_id,p.service_call,p.is_steward,p.user_name,p.place_name,p.create_at,p.status,
	SUM(IF(ps.status>0, 1, 0))staff_num,SUM(IF(ps.status=1, 1, 0))staff_online_num,p.service_config config`
	db := global.Orm.Table("places p").Select(fields)
	db.Joins("LEFT JOIN places_staff ps ON p.id = ps.place_id")

	if param.IsAdmin != helper.TypeNumIsAdminOperator && param.IsAdmin != helper.TypeNumIsAdminStaff {
		uList := NewUserDao().QueryChildUserIds(param.LoginUserId).Unwrap().([]int)
		pList := NewUserDao().GetPlacesIds(param.LoginUserId, uList).Unwrap().([]int)
		db.Where("p.id IN ?", pList)
	}

	if param.PlaceName != "" {
		PlaceStrSql := "%" + param.PlaceName + "%"
		db.Where("p.place_name LIKE ? OR p.id LIKE ?", PlaceStrSql, PlaceStrSql)
	}
	if param.IsSteward != 0 {
		db.Where("p.is_steward = ?", param.IsSteward)
	}

	db.Group("p.id")
	db.Limit(limit).Offset(offset).Find(&lst).Offset(-1).Limit(-1).Count(&count)
	//count = d.GetStewardPlaceListCount(param).Unwrap().(int64)
	return dingo.ErrorIf(db.Error, lst, count)
}

func (d *PlaceDao) GetStewardPlaceList(param *request.GetStewardPlaceListReq) *dingo.ErrorWrap {
	var (
		lst    []*request.GetStewardPlaceListRes
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)

	fields := `p.id,p.user_id,p.service_call,p.is_steward,p.user_name,p.place_name,p.create_at,p.status,
	SUM(IF(ps.status>0, 1, 0))staff_num,SUM(IF(ps.status=1, 1, 0))staff_online_num,p.service_config config`
	db := global.Orm.Table("places p").Select(fields)
	db.Joins("LEFT JOIN places_staff ps ON p.id = ps.place_id")

	if !helper.IsAdminAndStaff(param.IsAdmin, param.ParentId) {
		uList := NewUserDao().QueryChildUserIds(param.LoginUserId).Unwrap().([]int)
		pList := NewUserDao().GetPlacesIds(param.LoginUserId, uList).Unwrap().([]int)
		db.Where("p.id IN ?", pList)
	}

	if param.PlaceName != "" {
		PlaceStrSql := "%" + param.PlaceName + "%"
		db.Where("p.place_name LIKE ? OR p.id LIKE ?", PlaceStrSql, PlaceStrSql)
	}
	if param.IsSteward != 0 {
		db.Where("p.is_steward = ?", param.IsSteward)
	}
	if param.ProjectKey != "" {
		db.Where("p.project_label = ?", param.ProjectKey)
	}

	db.Group("p.id")
	db.Limit(limit).Offset(offset).Find(&lst).Offset(-1).Limit(-1).Count(&count)
	//count = d.GetStewardPlaceListCount(param).Unwrap().(int64)
	return dingo.ErrorIf(db.Error, lst, count)
}

func (d *PlaceDao) GetStewardPlaceListCount(param *request.GetStewardPlaceListReq) *dingo.ErrorWrap {
	var count int64

	db := global.Orm.Table("places p")

	if param.IsAdmin != helper.TypeNumIsAdminOperator {
		db.Where("p.user_id=?", param.LoginUserId)
	}

	if param.PlaceName != "" {
		PlaceStrSql := "%" + param.PlaceName + "%"
		db.Where("p.place_name LIKE ? OR p.id LIKE ?", PlaceStrSql, PlaceStrSql)
	}
	if param.IsSteward != 0 {
		db.Where("p.is_steward = ?", param.IsSteward)
	}

	db.Count(&count)
	return dingo.ErrorIf(db.Error, count)
}

// 获取设备、网点信息
func (d *PlaceDao) GetPlaceInfoByDeviceSn(deviceSn string) *dingo.ErrorWrap {
	m := &devices.DeviceWithPlaceInfo{}
	sql := "select d.shared_mode,d.device_type_id,d.device_type_name,d.device_sn,d.place_id,p.place_name,p.project_label " +
		"from places p inner join devices d on p.id = d.place_id where d.device_sn = ?"
	db := global.Orm.Debug().Raw(sql, deviceSn).Find(m)
	return dingo.ErrorIf(db.Error, m)
}

// 获取商户详情
func (d *PlaceDao) GetPlaceDetailById(id int) *dingo.ErrorWrap {
	m := placemodel.NewPlaceModel()
	sql := "select * from places  WHERE id = ? limit 1"
	db := global.Orm.Debug().Raw(sql, id).Find(&m)
	return dingo.ErrorIf(db.Error, m)
}

// InsertPlace 新增网点
func (d *PlaceDao) InsertPlace(m *placemodel.PlaceModel) *dingo.ErrorWrap {
	db := global.Orm.Debug().Table("places").Create(m)
	return dingo.ErrorIf(db.Error, m)
}

// 新增网点信息
func (d *UserDao) InsertPlaceInfo(param *request.PlaceInsertReq) *dingo.ErrorWrap {
	db := global.Orm
	// 终极上级
	uInfo := NewUserDao().GetUserInfoById(param.UserId).Unwrap().(*users.UserModel)
	userInfo := GetParentUserInfoById(uInfo)

	var entryStatus int8 // 1进场中 2进场结束
	if param.EntryMoney > 10 && param.EntryAt > 0 {
		entryStatus = 1
	} else {
		entryStatus = 0
	}
	if param.Status <= 0 {
		param.Status = 4 // 待审核
	}
	var isBusiness, isAd,isOpenFirst int
	if param.IsBusiness == 0 {
		isBusiness = 2
	} else {
		isBusiness = param.IsBusiness
	}
	if param.IsAd == 0 {
		isAd = 1
	} else {
		isAd = param.IsAd
	}
	if param.IsOpenFirst == 0 {
		isOpenFirst = 2
	} else {
		isOpenFirst = param.IsOpenFirst
	}

	p := placemodel.NewPlaceModel().Mutate(
		placemodel.WithCreateAt(dingo.Time(time.Now().Unix())),
		placemodel.WithPlaceName(param.PlaceName),
		placemodel.WithClassName(param.ClassName),
		placemodel.WithUserID(param.UserId),
		placemodel.WithUserName(param.Name),
		placemodel.WithLevel("E"),
		placemodel.WithStatus(int8(param.Status)),
		placemodel.WithProvince(param.Province),
		placemodel.WithCity(param.City),
		placemodel.WithCountry(param.County),
		placemodel.WithAddress(param.Address),
		placemodel.WithRegionIds(param.RegionIds),
		placemodel.WithEntryMoney(param.EntryMoney),
		placemodel.WithUserName(uInfo.Name),
		placemodel.WithAgentUserId(userInfo.ID),
		placemodel.WithAgentUserName(userInfo.Name),
		placemodel.WithEntryAt(dingo.Time(param.EntryAt)),
		placemodel.WithEntryStatus(entryStatus),
		placemodel.WithKaUserId(param.KaUserId),
		placemodel.WithHotelId(param.HotelId),
		placemodel.WithBranchUserId(param.BranchUserId),
		//新增地址
		placemodel.WithProvinceId(param.ProvinceId),
		placemodel.WithCityId(param.CityId),
		placemodel.WithCountyId(param.CountyId),
		placemodel.WithAreaId(param.AreaId),

		placemodel.WithProvince(param.Province),
		placemodel.WithCity(param.City),
		placemodel.WithCounty(param.County),

		//是否启用广告
		placemodel.WithIsAd(isAd),
		placemodel.WithIsBusiness(isBusiness),
		placemodel.WithIsOpenFirst(isOpenFirst),
		placemodel.WithProjectLabel(param.ProjectLabel),
		placemodel.WithPlaceDesc(param.PlaceDesc),

		placemodel.WithPlaceLicense(param.PlaceLicense),
		placemodel.WithPlaceFace(param.PlaceFace),
		placemodel.WithPlaceDesign(param.PlaceDesign),
		placemodel.WithMaintainerId(param.MaintainerId),
		
		placemodel.WithLatitude(param.Latitude),
		placemodel.WithLongitude(param.Longitude),

		placemodel.WithMscId(param.MscId),
	)
	db.Table("places").Create(&p)
	return dingo.ErrorIf(db.Error, p)

}

func (d *UserDao) UpdatePlaceInfoImg(param *request.PlaceInsertReq) *dingo.ErrorWrap {
	db := global.Orm
	m := &placemodel.PlaceModel{}
	m.UpdateAt = dingo.Time(time.Now().Unix())
	m.PlaceLicense = param.PlaceLicense
	m.PlaceFace = param.PlaceFace
	m.PlaceDesign = param.PlaceDesign
	db.Debug().Table("places").Select("place_license", "place_face", "place_design").
		Where("id = ?", param.Id).Model(&m).Updates(m)
	return dingo.ErrorIf(db.Error, m)
}

// 修改网点信息
func (d *UserDao) UpdatePlaceInfo(param *request.PlaceInsertReq, t int) *dingo.ErrorWrap {
	db := global.Orm
	// 终极上级
	uInfo := NewUserDao().GetUserInfoById(param.UserId).Unwrap().(*users.UserModel)
	userInfo := GetParentUserInfoById(uInfo)

	m := &placemodel.PlaceModel{}
	m.UpdateAt = dingo.Time(time.Now().Unix())
	m.PlaceName = param.PlaceName
	m.ClassName = param.ClassName
	m.UserID = param.UserId
	m.UserName = uInfo.UserName
	m.Province = param.Province
	m.City = param.City
	m.County = param.County
	m.Address = param.Address
	m.CityId = param.CityId
	m.ProvinceId = param.ProvinceId
	m.CountyId = param.CountyId
	m.RegionIds = param.RegionIds
	m.PlaceDesc = param.PlaceDesc

	m.PlaceLicense = param.PlaceLicense
	m.PlaceFace = param.PlaceFace
	m.PlaceDesign = param.PlaceDesign

	m.IsOpenFirst = param.IsOpenFirst

	// 审核不通过 更新后重新为审核状态
	if param.Status == helper.TypeNumPlaceStatusNoReview {
		m.Status = helper.TypeNumPlaceStatusINReview
	}

	if t == 1 {
		m.BranchUserId = param.BranchUserId // 关联分公司
		m.IsAd = param.IsAd                 // 是否开启广告
		m.IsBusiness = param.IsBusiness
		m.ProjectLabel = param.ProjectLabel // 关联项目
		m.HotelId = param.HotelId           // 携程母酒店ID
		var entryStatus int8                // 1进场中 2进场结束
		if param.EntryMoney > 10 && param.EntryAt > 0 {
			entryStatus = 1
		} else {
			entryStatus = 0
		}
		m.EntryMoney = param.EntryMoney
		m.EntryAt = dingo.Time(param.EntryAt)
		m.EntryStatus = entryStatus
		m.AgentUserId = userInfo.ID // 顶级用户
		m.AgentUserName = userInfo.UserName
		m.MaintainerId = param.MaintainerId
		m.MscID = param.MscId

		db.Debug().Table("places").Select("update_at", "place_name", "class_name", "user_id", "user_name",
			"province", "city", "county", "address", "province_id", "city_id", "county_id", "region_ids", "branch_user_id",
			"is_ad", "project_label", "hotel_id", "entry_status", "entry_at", "entry_money", "agent_user_id", "agent_user_name",
			"place_desc", "place_license", "place_face", "place_design", "is_business", "maintainer_id","is_open_first","msc_id").
			Where("id = ?", param.Id).Model(&m).Updates(m)
	} else {
		db.Debug().Table("places").Select("update_at", "place_name", "class_name", "user_id", "user_name",
			"province", "city", "county", "address", "province_id", "city_id", "county_id", "region_ids", "place_desc",
			"place_license", "place_face", "place_design", "is_open_first").
			Where("id = ?", param.Id).Model(&m).Updates(m)
	}

	return dingo.ErrorIf(db.Error, m)
}

// UpdatePlaceUserIdById
func (d *PlaceDao) UpdatePlaceUserIdById(ids []int, userId int) *dingo.ErrorWrap {

	sql := "update places set user_id = ?,update_at = ? where id in (?) "
	db := global.Orm.Exec(sql, userId, time.Now().Unix(), ids)

	log.Println("UpdatePlaceUserIdById方法的sql: ", sql)

	return dingo.ErrorIf(db.Error, true)
}

func (d *PlaceDao) SetPlaceAwaitingModerationStatus(param *request.SetPlaceAwaitingModerationStatusReq) *dingo.ErrorWrap {
	dbInfo := map[string]interface{}{
		"status": param.Status,
	}
	if param.Status == helper.TypeNumPlaceStatusYes {
		dbInfo["is_steward"] = helper.TypeNumCommonStatusTrue
	}
	dbInfo["place_desc"] = param.PlaceDesc

	db := global.Orm.Table("places").Where("id=?", param.PlaceId).Updates(&dbInfo)
	return dingo.ErrorIf(db.Error)
}

// GetPlaceAwaitingModerationList 获取网点列表API
func (d *PlaceDao) GetPlaceAwaitingModerationList(param *request.PlacesListReq) *dingo.ErrorWrap {
	var (
		lst    []*request.GetPlaceAwaitingModerationListRes
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)

	db := global.Orm.Debug().Table("places p").Select("p.*,pol.operation_user_name,pol.operation_user_id")
	db.Joins("LEFT JOIN place_operate_log pol ON p.id=pol.place_id")

	if param.PlaceName != "" {
		db.Where("p.place_name like ?", fmt.Sprint("%", param.PlaceName, "%"))
	}
	if param.Status > 0 {
		db.Where("p.status=?", param.Status)
	}

	db.Order("p.id desc")
	db.Limit(limit).Offset(offset).Find(&lst).Select("p.id").Limit(-1).Offset(-1).Count(&count)

	return dingo.ErrorIf(db.Error, lst, count)
}

// GetPlaceList 获取网点列表API
func (d *PlaceDao) GetAllPlaceList(param *request.PlacesListReq) *dingo.ErrorWrap {

	var (
		lst    []*placeresp.PlaceListByAll
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)

	tableLast := wechatpay.StrJoin("orders_", time.Now().AddDate(0, -1, 0).Format("2006_01"))
	tableNow := wechatpay.StrJoin("orders_", time.Now().Format("2006_01"))
	db := global.Orm.Debug().Table("places p").
		Select("p.*,u.name,u.phone,u.parent_id,u.profit_proportion,d.device_count,b.branch_name,b.branch_user_name," +
			"lorder.last_month_settlement,norder.now_month_settlement," +
			"r.receive_time,parent.name as parent_user_name,parent.user_name as parent_name,ploy.range,ploy.num").
		Joins("left join users u on p.user_id = u.id").
		Joins("left join users parent on u.parent_id = parent.id").
		//Joins("left join (SELECT `name` as parent_name,user_name as parent_user_name,id as pid FROM users GROUP BY parent_id) as pu ON u.parent_id = pu.pid").
		Joins("left join (SELECT count(place_id) as device_count,place_id FROM devices WHERE place_id > 0 GROUP BY place_id) as d ON p.id = d.place_id").
		Joins("left join (SELECT receive_time,place_id FROM logistics GROUP BY place_id) as r ON p.id = r.place_id").
		Joins("left join (SELECT `name` as branch_name,user_name as branch_user_name,id as b_user_id FROM users WHERE is_admin = 5) as b ON p.branch_user_id = b.b_user_id").
		Joins("left join (SELECT SUM(settlement_money) as last_month_settlement,place_id FROM " + tableLast + " WHERE is_draw = 0 and state = 5 GROUP BY place_id) as lorder ON p.id = lorder.place_id").
		Joins("left join (SELECT SUM(settlement_money) as now_month_settlement,place_id FROM " + tableNow + " WHERE is_draw = 0 and state = 5 GROUP BY place_id) as norder ON p.id = norder.place_id").
		Joins("left join (SELECT id,`range`,`num`,place_id FROM ploys WHERE place_id > 0 and shared_mode = 'pcl' GROUP BY place_id) as ploy ON p.id = ploy.place_id")

	if param.PlaceName != "" {
		db.Where("p.place_name like ?", fmt.Sprint("%", param.PlaceName, "%"))
	} // 门店名称-模糊查找
	if param.Name != "" {
		db.Where("u.name = ?", param.Name)
	} // 姓名
	if param.Phone != "" {
		db.Where("u.phone = ?", param.Phone)
	} // 手机号码
	if param.ProjectLabel != "" {
		db.Where("p.project_label = ?", param.ProjectLabel)
	} // 按项目
	// 城市查询
	if param.ProvinceId > 0 {
		db.Where("p.province_id = ?", param.ProvinceId)
	}
	if param.CityId > 0 {
		db.Where("p.city_id = ?", param.CityId)
	}
	if param.CountyId > 0 {
		db.Where("p.county_id = ?", param.CountyId)
	}
	if param.AgentUserId > 0 {
		if param.IsRel == 1 { // 关联
			placesBranchIds := NewUserDao().GetPlacesId(param.AgentUserId).Unwrap().([]int) // 查询用户ID下的所有关联门店
			placesIds := utils.RemoveRepByMap(placesBranchIds)                              // 去除门店
			db.Where("p.id in (?)", placesIds)
		} else if param.IsRel == 2 { // 不关联
			userIdArr := NewUserDao().QueryChildUserIds(param.AgentUserId).Unwrap().([]int) // 查询用户ID下所有下级用户ID
			placeIdArr := NewPlaceDao().GetPlaceByIds(userIdArr).Unwrap().([]int)           // 下级用户ID 下的门店
			db.Where("p.id in (?)", placeIdArr)
		} else { // 全部
			placesBranchIds := NewUserDao().GetPlacesId(param.AgentUserId).Unwrap().([]int) // 查询用户ID下的所有关联门店
			userIdArr := NewUserDao().QueryChildUserIds(param.AgentUserId).Unwrap().([]int) // 查询用户ID下所有下级用户ID
			placeIdArr := NewPlaceDao().GetPlaceByIds(userIdArr).Unwrap().([]int)           // 下级用户ID 下的门店
			placesBranchIds = append(placesBranchIds, placeIdArr...)                        // 合并门店
			placesIds := utils.RemoveRepByMap(placesBranchIds)                              // 去重门店
			db.Where("p.id in (?)", placesIds)
		}
	}

	db.Order("p.id desc")
	db.Limit(limit).Offset(offset).Find(&lst).Limit(-1).Offset(-1).Count(&count)

	return dingo.ErrorIf(db.Error, lst, count)
}


// GetAllDrawPlaceList 获取网点列表API
func (d *PlaceDao) GetAllDrawPlaceList(param *request.PlacesListReq) *dingo.ErrorWrap {

	var (
		lst    []*placeresp.PlaceListByAll
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)

	tableLast := wechatpay.StrJoin("orders_", time.Now().AddDate(0, -1, 0).Format("2006_01"))
	tableNow := wechatpay.StrJoin("orders_", time.Now().Format("2006_01"))
	db := global.Orm.Debug().Table("places p").
		Select("p.*,u.name,u.phone,u.parent_id,u.profit_proportion,d.device_count,b.branch_name,b.branch_user_name," +
			"lorder.last_month_settlement,norder.now_month_settlement," +
			"r.receive_time,parent.name as parent_user_name,parent.user_name as parent_name,ploy.range,ploy.num").
		Joins("left join users u on p.user_id = u.id").
		Joins("left join users parent on u.parent_id = parent.id").
		//Joins("left join (SELECT `name` as parent_name,user_name as parent_user_name,id as pid FROM users GROUP BY parent_id) as pu ON u.parent_id = pu.pid").
		Joins("left join (SELECT count(place_id) as device_count,place_id FROM devices WHERE place_id > 0 GROUP BY place_id) as d ON p.id = d.place_id").
		Joins("left join (SELECT receive_time,place_id FROM logistics GROUP BY place_id) as r ON p.id = r.place_id").
		Joins("left join (SELECT `name` as branch_name,user_name as branch_user_name,id as b_user_id FROM users WHERE is_admin = 5) as b ON p.branch_user_id = b.b_user_id").
		Joins("left join (SELECT SUM(settlement_money) as last_month_settlement,place_id FROM " + tableLast + " WHERE is_draw = 0 and state = 5 GROUP BY place_id) as lorder ON p.id = lorder.place_id").
		Joins("left join (SELECT SUM(settlement_money) as now_month_settlement,place_id FROM " + tableNow + " WHERE is_draw = 0 and state = 5 GROUP BY place_id) as norder ON p.id = norder.place_id").
		Joins("left join (SELECT id,`range`,`num`,place_id FROM ploys WHERE place_id > 0 and shared_mode = 'pcl' GROUP BY place_id) as ploy ON p.id = ploy.place_id")

	if param.PlaceName != "" {
		db.Where("p.place_name like ?", fmt.Sprint("%", param.PlaceName, "%"))
	} // 门店名称-模糊查找
	if param.Name != "" {
		db.Where("u.name = ?", param.Name)
	} // 姓名
	if param.Phone != "" {
		db.Where("u.phone = ?", param.Phone)
	} // 手机号码
	if param.ProjectLabel != "" {
		db.Where("p.project_label = ?", param.ProjectLabel)
	} // 按项目
	// 城市查询
	if param.ProvinceId > 0 {
		db.Where("p.province_id = ?", param.ProvinceId)
	}
	if param.CityId > 0 {
		db.Where("p.city_id = ?", param.CityId)
	}
	if param.CountyId > 0 {
		db.Where("p.county_id = ?", param.CountyId)
	}
	if param.AgentUserId > 0 {
		if param.IsRel == 1 { // 关联
			placesBranchIds := NewUserDao().GetPlacesId(param.AgentUserId).Unwrap().([]int) // 查询用户ID下的所有关联门店
			placesIds := utils.RemoveRepByMap(placesBranchIds)                              // 去除门店
			db.Where("p.id in (?)", placesIds)
		} else if param.IsRel == 2 { // 不关联
			userIdArr := NewUserDao().QueryChildUserIds(param.AgentUserId).Unwrap().([]int) // 查询用户ID下所有下级用户ID
			placeIdArr := NewPlaceDao().GetPlaceByIds(userIdArr).Unwrap().([]int)           // 下级用户ID 下的门店
			db.Where("p.id in (?)", placeIdArr)
		} else { // 全部
			placesBranchIds := NewUserDao().GetPlacesId(param.AgentUserId).Unwrap().([]int) // 查询用户ID下的所有关联门店
			userIdArr := NewUserDao().QueryChildUserIds(param.AgentUserId).Unwrap().([]int) // 查询用户ID下所有下级用户ID
			placeIdArr := NewPlaceDao().GetPlaceByIds(userIdArr).Unwrap().([]int)           // 下级用户ID 下的门店
			placesBranchIds = append(placesBranchIds, placeIdArr...)                        // 合并门店
			placesIds := utils.RemoveRepByMap(placesBranchIds)                              // 去重门店
			db.Where("p.id in (?)", placesIds)
		}
	}

	db.Order("norder.now_month_settlement desc")
	db.Limit(limit).Offset(offset).Find(&lst).Limit(-1).Offset(-1).Count(&count)

	return dingo.ErrorIf(db.Error, lst, count)
}

// GetPlaceList 获取网点列表API
func (d *PlaceDao) GetPlaceList(param *request.PlacesListReq, loginUserId int) *dingo.ErrorWrap {

	var (
		lst    []*placeresp.PlaceList
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)

	tableLast := wechatpay.StrJoin("orders_", time.Now().AddDate(0, -1, 0).Format("2006_01"))
	tableNow := wechatpay.StrJoin("orders_", time.Now().Format("2006_01"))
	db := global.Orm.Debug().Table("places p").
		Select("p.*,u.name,u.phone,u.parent_id,u.profit_proportion,d.device_count,b.branch_name,b.branch_user_name," +
			"lorder.last_month_settlement,norder.now_month_settlement," +
			"r.receive_time,parent.name as parent_user_name,parent.user_name as parent_name").
		Joins("left join users u on p.user_id = u.id").
		Joins("left join users parent on u.parent_id = parent.id").
		//Joins("left join (SELECT `name` as parent_name,user_name as parent_user_name,id as pid FROM users GROUP BY parent_id) as pu ON u.parent_id = pu.pid").
		Joins("left join (SELECT count(place_id) as device_count,place_id FROM devices WHERE place_id > 0 GROUP BY place_id) as d ON p.id = d.place_id").
		Joins("left join (SELECT receive_time,place_id FROM logistics GROUP BY place_id) as r ON p.id = r.place_id").
		Joins("left join (SELECT `name` as branch_name,user_name as branch_user_name,id as b_user_id FROM users WHERE is_admin = 5) as b ON p.branch_user_id = b.b_user_id").
		Joins("left join (SELECT SUM(settlement_money) as last_month_settlement,place_id FROM " + tableLast + " WHERE is_draw = 0 and state = 5 GROUP BY place_id) as lorder ON p.id = lorder.place_id").
		Joins("left join (SELECT SUM(settlement_money) as now_month_settlement,place_id FROM " + tableNow + " WHERE is_draw = 0 and state = 5 GROUP BY place_id) as norder ON p.id = norder.place_id")

	if param.PlaceName != "" {
		db.Where("p.place_name like ?", fmt.Sprint("%", param.PlaceName, "%"))
	} // 门店名称
	if param.Status > 0 {
		db.Where("p.status = ?", param.Status)
	} // 状态
	if param.AreaCode != "" {
		db.Where("p.area_code in (?)", param.AreaCode)
	} // 区域
	if param.ProjectLabel != "" {
		db.Where("p.project_label = ?", param.ProjectLabel)
	} // 项目
	if param.Name != "" {
		db.Where("u.name = ?", param.Name)
	} // 所属人
	if param.Phone != "" {
		db.Where("u.phone = ?", param.Phone)
	} // 手机号码
	if param.ProvinceId > 0 {
		db.Where("p.province_id = ?", param.ProvinceId)
	} // 省
	if param.CityId > 0 {
		db.Where("p.city_id = ?", param.CityId)
	} // 市
	if param.CountyId > 0 {
		db.Where("p.county_id = ?", param.CountyId)
	}
	if param.AgentUserId > 0 {
		loginUserId = param.AgentUserId
	} // 用户名称查询
	if param.MaintainerId > 0 {
		db.Where("p.maintainer_id = ?", param.MaintainerId)
	} // 运维
	if param.MscId > 0 {
		db.Where("p.msc_id = ?", param.MscId)
	}
	if param.IsSteward > 0 {
		db.Where("p.is_steward = ?", param.IsSteward)
	}

	if loginUserId != 2 { // loginUserId为 2 时  取所有，这样就不用递归查询门店ID了，也不需要使用 in 条件了
		if param.IsRel == 1 { // 关联
			placesBranchIds := NewUserDao().GetPlacesId(loginUserId).Unwrap().([]int) // 查询用户ID下的所有关联门店
			placesIds := utils.RemoveRepByMap(placesBranchIds)                        // 去除门店
			db.Where("p.id in (?)", placesIds)
		} else if param.IsRel == 2 { // 不关联
			userIdArr := NewUserDao().QueryChildUserIds(loginUserId).Unwrap().([]int) // 查询用户ID下所有下级用户ID
			placeIdArr := NewPlaceDao().GetPlaceByIds(userIdArr).Unwrap().([]int)     // 下级用户ID 下的门店
			db.Where("p.id in (?)", placeIdArr)
		} else { // 全部
			placesBranchIds := NewUserDao().GetPlacesId(loginUserId).Unwrap().([]int) // 查询用户ID下的所有关联门店
			userIdArr := NewUserDao().QueryChildUserIds(loginUserId).Unwrap().([]int) // 查询用户ID下所有下级用户ID
			placeIdArr := NewPlaceDao().GetPlaceByIds(userIdArr).Unwrap().([]int)     // 下级用户ID 下的门店
			placesBranchIds = append(placesBranchIds, placeIdArr...)                  // 合并门店
			placesIds := utils.RemoveRepByMap(placesBranchIds)                        // 去重门店
			db.Where("p.id in (?)", placesIds)
		}
	}

	// 创建时间查询
	if param.BeginTime != "" {
		beginTime := strings.Split(param.BeginTime, ",")
		db.Where("p.create_at >= ? and p.create_at <= ?", beginTime[0], beginTime[1])
	}

	db.Order("p.id desc")

	db.Limit(limit).Offset(offset).Find(&lst).Limit(-1).Offset(-1).Count(&count)

	return dingo.ErrorIf(db.Error, lst, count)
}

func (d *PlaceDao) GetPlaceListByMsc(param *request.MscPlacesListReq) *dingo.ErrorWrap {

	var (
		lst    []*placeresp.MscPlaceListResp
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)
	//SELECT p.*,d.device_count,l.receive_time,IFNULL(l.status,0) as logistics_status FROM places p
	//left join users u on p.user_id = u.id
	//left join (SELECT count(place_id) as device_count,place_id FROM devices WHERE place_id > 0 GROUP BY place_id)
	//as d ON p.id = d.place_id
	//left join logistics l ON l.place_id = p.id WHERE p.msc_id = 407465 and IFNULL(l.status,0) != 3 ORDER BY p.id desc LIMIT 10
	db := global.Orm.Debug().Table("places p").
		Select("p.*,d.device_count," +
			"l.receive_time,IFNULL(l.status,0) as logistics_status").
		Joins("left join users u on p.user_id = u.id").
		Joins("left join (SELECT count(place_id) as device_count,place_id FROM devices WHERE place_id > 0 GROUP BY place_id) as d ON p.id = d.place_id").
		Joins("left join logistics l ON l.place_id = p.id")
	db.Where("IFNULL(l.status,0) != ?", 3) // 状态未签收
	// 所属供应链
	if !helper.IsAdminAndStaff(param.IsAdmin, param.ParentId) {
		db.Where("p.msc_id = ?", param.LoginUserId)
	}
	// 门店名称搜索
	if param.PlaceName != "" {
		db.Where("p.place_name like ?", fmt.Sprint("%", param.PlaceName, "%"))
	}

	db.Order("p.id desc")

	db.Limit(limit).Offset(offset).Find(&lst).Limit(-1).Offset(-1).Count(&count)

	return dingo.ErrorIf(db.Error, lst, count)
}

func (d *PlaceDao) ExportAllSmallPlacePloyList(param *request.PlacesListReq) *dingo.ErrorWrap {

	var (
		lst    []*placeresp.SmallPlacePloyWithUser
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)

	db := global.Orm.Debug().Table("places p").
		Select("p.*,u.name,u.phone,u.parent_id,u.profit_proportion,u.sm_profit_proportion,?", gorm.Expr("concat(parent.user_name,'-',parent.name) parent_name")).
		Joins("left join users u on p.user_id = u.id").
		Joins("left join users parent on u.parent_id = parent.id")

	if param.PlaceName != "" {
		db.Where("p.place_name like ?", fmt.Sprint("%", param.PlaceName, "%"))
	} // 门店名称-模糊查找
	if param.Name != "" {
		db.Where("u.name = ?", param.Name)
	}
	if param.Phone != "" {
		db.Where("u.phone = ?", param.Phone)
	}
	if param.ProjectLabel != "" {
		db.Where("p.project_label = ?", param.ProjectLabel)
	}
	// 城市查询
	if param.ProvinceId > 0 {
		db.Where("p.province_id = ?", param.ProvinceId)
	}
	if param.CityId > 0 {
		db.Where("p.city_id = ?", param.CityId)
	}
	if param.CountyId > 0 {
		db.Where("p.county_id = ?", param.CountyId)
	}
	if param.AgentUserId > 0 {
		userIdArr := NewUserDao().QueryChildUserIds(param.AgentUserId).Unwrap().([]int)
		db.Where("u.id in (?)", userIdArr)
	}

	db.Order("p.used_rate,p.create_at desc")
	db.Limit(limit).Offset(offset).Find(&lst).Limit(-1).Offset(-1).Count(&count)

	return dingo.ErrorIf(db.Error, lst, count)
}

// 获取商户列表 - 公众号商户菜单
func (d *PlaceDao) GetPlaceListByPlace(param *request.PlaceListByPlaceReq, IsAdmin uint8) *dingo.ErrorWrap {
	var (
		lst    []*placeresp.PlacesWithUser
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)
	var placesIdArr []int
	if IsAdmin != helper.TypeNumIsAdminOperator && param.Type != "direct" {
		userIdArr := NewUserDao().QueryChildUserIds(param.UserId).Unwrap().([]int)
		placesIdArr = NewUserDao().GetPlacesIds(param.UserId, userIdArr).Unwrap().([]int)

		if len(placesIdArr) == 0 {
			return dingo.ErrorIf(nil, lst, count)
		}
	}

	db := global.Orm.Table("places p").
		Select("p.*,u.name,u.phone,u.avatar,u.user_no").
		Joins("left join users u on p.user_id = u.id")
	if param.Type == "all" { // 全部
		if IsAdmin != helper.TypeNumIsAdminOperator {
			db.Where("p.id in ?", placesIdArr)
		}
	}
	if param.Type == "direct" { // 直属商户
		db.Where("p.user_id = ?", param.UserId) // 获取下级商户列表
	}
	if param.Type == "children" { // 下级商户
		if IsAdmin != helper.TypeNumIsAdminOperator {
			db.Where("p.user_id<>? AND p.id in ?", param.UserId, placesIdArr) // 获取下级商户列表
		} else {
			db.Where("p.user_id<>?", param.UserId)
		}
	}
	if param.PlaceName != "" {
		placeName := "%" + param.PlaceName + "%"
		db.Where("p.place_name LIKE ?", placeName)
	}
	if param.Name != "" {
		uName := "%" + param.Name + "%"
		db.Where("u.name LIKE ?", uName)
	}
	if param.Phone != "" {
		db.Where("u.phone = ?", param.Phone)
	}
	db.Limit(limit).Offset(offset).Order("p.create_at DESC").Find(&lst).Limit(-1).Offset(-1).Count(&count)
	return dingo.ErrorIf(db.Error, lst, count)
}

// 获取门店列表 - B端运营平台（APP、小程序）
func (d *PlaceDao) GetPlaceListWithUser(param *request.PlaceListByPlaceReq, IsAdmin uint8) *dingo.ErrorWrap {
	var (
		lst    []*placeresp.GetPlaceIdWithHotelId
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)
	var placesIdArr []int
	if IsAdmin != helper.TypeNumIsAdminOperator && param.Type != "direct" {
		userIdArr := NewUserDao().QueryChildUserIds(param.UserId).Unwrap().([]int)
		placesIdArr = NewUserDao().GetPlacesIds(param.UserId, userIdArr).Unwrap().([]int)

		if len(placesIdArr) == 0 {
			return dingo.ErrorIf(nil, lst, count)
		}
	}

	db := global.Orm.Table("places p").
		Select("p.*,u.name,u.phone,u.avatar,u.user_no").
		Joins("left join users u on p.user_id = u.id")

	if param.Type == "all" { // 全部
		if IsAdmin != helper.TypeNumIsAdminOperator {
			db.Where("p.id in ?", placesIdArr)
		}
	}
	if param.Type == "direct" { // 直属商户
		db.Where("p.user_id = ?", param.UserId) // 获取下级商户列表
	}
	if param.Type == "children" { // 下级商户
		if IsAdmin != helper.TypeNumIsAdminOperator {
			db.Where("p.user_id<>? AND p.id in ?", param.UserId, placesIdArr) // 获取下级商户列表
		} else {
			db.Where("p.user_id<>?", param.UserId)
		}
	}
	if param.PlaceName != "" {
		placeName := "%" + param.PlaceName + "%"
		db.Where("p.place_name LIKE ?", placeName)
	}
	if param.Name != "" {
		uName := "%" + param.Name + "%"
		db.Where("u.name LIKE ?", uName)
	}
	if param.Phone != "" {
		db.Where("u.phone = ?", param.Phone)
	}
	db.Limit(limit).Offset(offset).Order("p.create_at DESC").Find(&lst).Limit(-1).Offset(-1).Count(&count)
	return dingo.ErrorIf(db.Error, lst, count)
}

// GetPlaceByparentId 获取某个用户下的所有代理商用户ID
func (d *PlaceDao) GetPlaceByparentId(parentId int) *dingo.ErrorWrap {
	lst := make([]*placemodel.PlaceModel, 0)
	sql := "select p.* from places p LEFT JOIN users u on p.user_id = u.id WHERE u.parent_id = ?"
	db := global.Orm.Debug().Raw(sql, parentId).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

// GetPlaceByparentId 获取某个用户下的所有代理商用户ID
func (d *PlaceDao) GetPlaceByParentIds(parentIds []int) *dingo.ErrorWrap {
	lst := make([]*placemodel.PlaceModel, 0)
	sql := "select p.* from places p LEFT JOIN users u on p.user_id = u.id WHERE u.id IN ?"
	db := global.Orm.Raw(sql, parentIds).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

func (d *PlaceDao) GetPlaceByUserId(userId int) *dingo.ErrorWrap {
	lst := make([]*placemodel.PlaceModel, 0)
	sql := "select * from places where user_id = ?"
	db := global.Orm.Debug().Raw(sql, userId).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

// 获取某个分公司用户下的所有网点ID
func (d *PlaceDao) GetPlaceByBranchUserId(branchUserId int) *dingo.ErrorWrap {
	lst := make([]*placemodel.PlaceModel, 0)
	sql := "select p.* from places p where p.branch_user_id=?"
	db := global.Orm.Debug().Raw(sql, branchUserId).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

//分公司获取网点Id
func (d *PlaceDao) GetPlaceByBranchUserIdList(branchUserId int) *dingo.ErrorWrap {
	lst := make([]int, 0)
	sql := "select id from places p where p.branch_user_id=?"
	db := global.Orm.Debug().Raw(sql, branchUserId).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

func (d *PlaceDao) GetPlaceByIds(parentIds []int) *dingo.ErrorWrap {
	var placeIds []int
	if len(parentIds) == 0 {
		return dingo.ErrorIf(nil, placeIds)
	}

	sql := "select p.id from places p LEFT JOIN users u on p.user_id = u.id WHERE u.id IN ?"
	db := global.Orm.Raw(sql, parentIds).Find(&placeIds)
	return dingo.ErrorIf(db.Error, placeIds)
}

func (d *PlaceDao) GetPlaceByPlaceIds(ids []int) *dingo.ErrorWrap {
	var lst []*placeresp.GetPlaceIdWithHotelId
	db := global.Orm.Table("places").Where("id IN ?", ids).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

// GetPlaceList 获取网点列表API
func (d *PlaceDao) GetPlaceListNoPager(placeName string, loginUserId int, isAdmin uint8) *dingo.ErrorWrap {

	var lst []placeresp.GetPlaceIdWithHotelId
	db := global.Orm.Debug().Table("places p").
		Select("p.*").
		Joins("left join users u on p.user_id = u.id")
	if placeName != "" {
		db.Where("p.place_name like ?", fmt.Sprint("%", placeName, "%"))
		//db.Where("concat(user_name,real_name) like ?", fmt.Sprint("%", param.SearchText, "%"))
	}
	// 如果是文员登录，只展示自己维护的商户
	if isAdmin == 4 {
		db.Where("p.maintainer_id = ? ", loginUserId)
	}
	// 如果是运营商或代理商登录，只展示旗下所有商户
	if isAdmin > 4 {

		// 获取该用户下的所有代理商的用户ID
		pidArr := []int{loginUserId}
		userIdArr := make([]int, 0)
		isRecursive := true
		// 递归 无限查询下级
		for isRecursive {
			tempUserIdArr := NewUserDao().GetUserIdByPid(pidArr).Unwrap().([]int)

			if len(tempUserIdArr) == 0 {
				isRecursive = false
			} else {
				userIdArr = append(userIdArr, tempUserIdArr...)
				pidArr = tempUserIdArr
				//log.Println("当前pid数组：",pidArr)
				//log.Println("当前userIdArr数组：",userIdArr)
			}
		}
		db.Where("u.id in (?)", userIdArr)
		//db.Where("u.parent_id = ? ", loginUserId)
	}

	db.Order("p.id asc").Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

// 根据维护者ID查询商户表
func (d *PlaceDao) GetPlaceListByMaintainerId(maintainerId int) *dingo.ErrorWrap {

	//var lst []*placemodel.PlaceModel
	lst := make([]*placemodel.PlaceModel, 0)
	db := global.Orm.Debug().Table("places").
		Where("maintainer_id = ?", maintainerId).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

func (d *PlaceDao) GetPlaceListByName(placeName string) *dingo.ErrorWrap {

	var lst []placeresp.GetPlaceIdWithHotelId
	db := global.Orm.Table("places").
		Where("place_name like ?", fmt.Sprint("%", placeName, "%")).
		Order("id asc").Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

// UpdatePlaceById 修改网点信息
func (d *PlaceDao) UpdatePlaceById(m *placemodel.PlaceModel) *dingo.ErrorWrap {
	m.UpdateAt = dingo.Time(time.Now().Unix())
	db := global.Orm.Table("places").Where("id = ?", m.Id).Model(&m).Updates(m)
	return dingo.ErrorIf(db.Error, m)
}

// UpdatePlaceStatus 更新状态
func (d *PlaceDao) UpdatePlaceStatus(id int, status int8) *dingo.ErrorWrap {
	sql := "update places set status = ? where id = ?"
	db := global.Orm.Exec(sql, status, id)
	return dingo.ErrorIf(db.Error, true)
}

// 更新设备台数
func (d *PlaceDao) UpdatePlaceCount(id int, total int64) *dingo.ErrorWrap {
	sql := "update places set device_count = ? where id = ?"
	db := global.Orm.Exec(sql, total, id)
	return dingo.ErrorIf(db.Error, true)
}

// DeletePlaceById 根据ID删除网点信息
func (d *PlaceDao) DeletePlaceById(id int) *dingo.ErrorWrap {
	db := global.Orm.Exec("delete from places where id = ?", id)
	return dingo.ErrorIf(db.Error, true)
}

// GetPlaceById 获取网点详情API
func (d *PlaceDao) GetPlaceById(id int) *dingo.ErrorWrap {

	m := placemodel.NewPlaceModel()
	db := global.Orm.Table("places").Where("id = ?", id).Find(m)
	return dingo.ErrorIf(db.Error, m)

}

// 获取某个代理商下的所有网点
func (d *PlaceDao) GetPlaceIdByUserId(userId []int) *dingo.ErrorWrap {
	placeModelLst := make([]*placemodel.PlaceModel, 0)
	sql := "select id from places where user_id in (?)"
	db := global.Orm.Raw(sql, userId).Find(&placeModelLst)

	//log.Print("获取某个代理商下的所有网点的SQL为：", sql, " userId数组为：", userId)
	placeIdArr := make([]int, 0)
	//placeIdArr := []int{}
	for _, userModel := range placeModelLst {
		//log.Println("placeIdArr dao数组：", placeIdArr)
		placeIdArr = append(placeIdArr, userModel.Id)
	}
	return dingo.ErrorIf(db.Error, placeIdArr)
}

// 获取某用户下所有商户统计和设备统计
func (d *PlaceDao) TotalPlaceByUserId(userId []int) *dingo.ErrorWrap {
	placeTotalModel := &placeresp.TotalPlaceDevices{}
	sql := "SELECT count(1) AS place_count ,SUM(IFNULL(device_count,0)) AS device_count " +
		"from places where user_id in(?)"
	db := global.Orm.Raw(sql, userId).Find(&placeTotalModel)
	return dingo.ErrorIf(db.Error, placeTotalModel)
}

// GenPlaceUsedRateList 计算网点30天的使用率
func (d *PlaceDao) GenPlaceUsedRateList() *dingo.ErrorWrap {
	var lst []placeresp.PlaceUsedRateRankList

	// 1、订单表orders-获取网点最近30天的 订单数、订单总额  -- 得到表a
	// 2、网点表places 左联接关联 表a (所有网点信息对应的订单数) -- 得到表b
	// 3、设备表devices-获取网点的设备条数 -- 得到表 c
	// 4、计算使用率、客单价
	//    公式：使用率=订单数/(设备数*30天)
	//    公式：客单价=订单总额/订单数
	//	sql := `SELECT b.place_id,b.place_name,IFNULL(c.device_count,0) as device_count,
	//IFNULL(b.order_total,0) as order_total,IFNULL(b.turnover,0) as turnover,
	//IFNULL(b.order_total/(c.device_count*30)*100,0) as usage_rate,
	//IFNULL((b.turnover/b.order_total)/100,0) as arpa FROM
	//(
	//	SELECT p.id as place_id,p.place_name,a.order_total,a.turnover FROM places p
	//	LEFT JOIN (
	//		SELECT place_id,count(1) as order_total,IFNULL(SUM(o.settlement_money),0) as turnover FROM orders o
	//		WHERE date_sub(curdate(), interval 31 day) <= date_add(date_format(curdate(),'%Y-%m-%d'), interval -1 day) GROUP BY place_id
	//	) a ON a.place_id = p.id
	//) b
	//LEFT JOIN (
	//	SELECT count(1) as device_count,place_id FROM devices GROUP BY place_id
	//) c ON b.place_id = c.place_id
	//ORDER BY usage_rate desc`

	sql := `SELECT p.id as place_id,p.place_name,p.level,
IFNULL(d.device_count,0) as device_count,
IFNULL(o.order_total,0) as order_total,
IFNULL(o.turnover,0) as turnover,
IFNULL(o.order_total/(d.device_count*30)*100,0) as usage_rate,
IFNULL((o.turnover/o.order_total)/100,0) as arpa FROM places p 
LEFT JOIN (
	SELECT place_id,count(1) as order_total,IFNULL(SUM(settlement_money),0) as turnover FROM orders WHERE
	DATE_FORMAT(FROM_UNIXTIME(create_at),'%Y-%m-%d') >= date_sub(curdate(), interval 31 day) AND 
	DATE_FORMAT(FROM_UNIXTIME(create_at),'%Y-%m-%d') <= date_add(date_format(curdate(),'%Y-%m-%d'), interval -1 day)
	GROUP BY place_id
) as o ON p.id = o.place_id 
LEFT JOIN (
	SELECT count(1) as device_count,place_id FROM devices GROUP BY place_id
) as d ON p.id = d.place_id ORDER BY usage_rate desc`
	db := global.Orm.Raw(sql).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

// 测试用，以后不用
func (d *PlaceDao) GenPlaceUsedRateListTest(sday, eday int) *dingo.ErrorWrap {
	var lst []placeresp.PlaceUsedRateRankList
	sql := `SELECT p.id as place_id,p.place_name,p.level,
IFNULL(d.device_count,0) as device_count,
IFNULL(o.order_total,0) as order_total,
IFNULL(o.turnover,0) as turnover,
IFNULL(o.order_total/(d.device_count*30)*100,0) as usage_rate,
IFNULL((o.turnover/o.order_total)/100,0) as arpa FROM places p 
LEFT JOIN (
	SELECT place_id,count(1) as order_total,IFNULL(SUM(settlement_money),0) as turnover FROM orders WHERE
	DATE_FORMAT(FROM_UNIXTIME(create_at),'%Y-%m-%d') >= date_sub(curdate(), interval ? day) AND 
	DATE_FORMAT(FROM_UNIXTIME(create_at),'%Y-%m-%d') <= date_add(date_format(curdate(),'%Y-%m-%d'), interval -? day)
	GROUP BY place_id
) as o ON p.id = o.place_id 
LEFT JOIN (
	SELECT count(1) as device_count,place_id FROM devices GROUP BY place_id
) as d ON p.id = d.place_id ORDER BY usage_rate desc`
	db := global.Orm.Raw(sql, sday, eday).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

func (d *PlaceDao) UpdatePlaceRateById(m *placemodel.PlaceModel) *dingo.ErrorWrap {
	db := global.Orm.Table("places").Model(&m).
		Select("level", "used_rate").
		Updates(m)
	return dingo.ErrorIf(db.Error, true)
}

// GetPlaceList 获取网点列表API
func (d *PlaceDao) GetPlaceLevelLogList(param *request.PlacesLevelListReq, loginUserId int) *dingo.ErrorWrap {
	var (
		lst    []*placemodel.PlaceLevelLogModel
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)

	beginTime7, endTime7 := wechatpay.GetLastDayStartEnd(7)
	beginTime15, endTime15 := wechatpay.GetLastDayStartEnd(15)
	beginTime30, endTime30 := wechatpay.GetLastDayStartEnd(30)
	beginTime60, endTime60 := wechatpay.GetLastDayStartEnd(60)
	beginTime90, endTime90 := wechatpay.GetLastDayStartEnd(90)

	// 获取所有商户
	db := global.Orm.Table("places p").
		Select("p.id as place_id,p.place_name,p.level,p.used_rate,l7.level as level7,l7.used_rate as used_rate7,l15.level as level15,l15.used_rate as used_rate15,"+
			"l30.level as level30,l30.used_rate as used_rate30,l60.level as level60,l60.used_rate as used_rate60,l90.level as level90,l90.used_rate as used_rate90").
		Joins("left join users u on p.user_id = u.id").
		Joins("left join (SELECT place_id,place_name,`level`,level_num,used_rate FROM place_level_log WHERE create_at >= ? and create_at <= ?)"+
			" as l7 on p.id = l7.place_id", beginTime7, endTime7).
		Joins("left join (SELECT place_id,place_name,`level`,level_num,used_rate FROM place_level_log WHERE create_at >= ? and create_at <= ?)"+
			" as l15 on p.id = l15.place_id", beginTime15, endTime15).
		Joins("left join (SELECT place_id,place_name,`level`,level_num,used_rate FROM place_level_log WHERE create_at >= ? and create_at <= ?)"+
			" as l30 on p.id = l30.place_id", beginTime30, endTime30).
		Joins("left join (SELECT place_id,place_name,`level`,level_num,used_rate FROM place_level_log WHERE create_at >= ? and create_at <= ?)"+
			" as l60 on p.id = l60.place_id", beginTime60, endTime60).
		Joins("left join (SELECT place_id,place_name,`level`,level_num,used_rate FROM place_level_log WHERE create_at >= ? and create_at <= ?)"+
			" as l90 on p.id = l90.place_id", beginTime90, endTime90)
	if param.PlaceName != "" {
		db.Where("p.place_name like ?", fmt.Sprint("%", param.PlaceName, "%"))
	}
	if len(param.Level) > 0 {
		db.Where("p.level in ?", param.Level)
	}
	if loginUserId != 2 { // loginUserId为 2 时  取所有，这样就不用递归查询门店ID了，也不需要使用 in 条件了
		placesBranchIds := NewUserDao().GetPlacesId(loginUserId).Unwrap().([]int) // 查询用户ID下的所有关联门店
		userIdArr := NewUserDao().QueryChildUserIds(loginUserId).Unwrap().([]int) // 查询用户ID下所有下级用户ID
		placeIdArr := NewPlaceDao().GetPlaceByIds(userIdArr).Unwrap().([]int)     // 下级用户ID 下的门店
		placesBranchIds = append(placesBranchIds, placeIdArr...)                  // 合并门店
		placesIds := utils.RemoveRepByMap(placesBranchIds)                        // 去重门店
		db.Where("p.id in (?)", placesIds)
	}

	db.Order("p.used_rate DESC")
	db.Limit(limit).Offset(offset).Find(&lst).Limit(-1).Offset(-1).Count(&count)

	return dingo.ErrorIf(db.Error, lst, count)
}

// GetPlaceLevelLogByPlaceId
func (d *PlaceDao) GetPlaceLevelLogByPlaceId(placeId int, day int) *dingo.ErrorWrap {

	m := placemodel.PlaceLevelLogModel{}
	sql := " SELECT * FROM place_level_log t WHERE place_id = ? " +
		" AND DATE_FORMAT(FROM_UNIXTIME(create_at),'%Y-%m-%d') = date_sub(curdate(), interval ? day)"

	db := global.Orm.Raw(sql, placeId, day).Find(&m)

	return dingo.ErrorIf(db.Error, m)
}

func (d *PlaceDao) GetPlaceLevelLogDateArr(placeIds []int, day int) *dingo.ErrorWrap {

	var m []*placemodel.PlaceLevelLogModel
	sql := " SELECT * FROM place_level_log t WHERE place_id in (?) " +
		" AND DATE_FORMAT(FROM_UNIXTIME(create_at),'%Y-%m-%d') = date_sub(curdate(), interval ? day)"

	db := global.Orm.Debug().Raw(sql, placeIds, day).Find(&m)

	return dingo.ErrorIf(db.Error, m)
}

func (d *PlaceDao) GetPlaceUserInfo(placeId int) *dingo.ErrorWrap {
	m := &placeresp.PlaceInfo{}
	db := global.Orm.Debug().
		Table("places p").
		Select("p.*,u.name,u.phone,u.phone_code,u.profit_type,"+
			"u.profit_proportion,u.sm_profit_proportion").
		Joins("left join users u on p.user_id = u.id").
		Where("p.id = ?", placeId).Find(m)

	return dingo.ErrorIf(db.Error, m)
}

// 获取省、市、县
func (d *PlaceDao) GetRegionsByLevel(level int) *dingo.ErrorWrap {
	lst := make([]*regions.RegionModel, 0)
	db := global.Orm.Debug().Table("lc_tencent_regions")
	if level > 0 {
		db.Where("level = ?", level)
	}
	db.Find(&lst)
	return dingo.ErrorIf(db.Error, lst)

}

// 获取省、市、县
func (d *PlaceDao) GetRegionsListByParent(parent int) *dingo.ErrorWrap {
	lst := make([]*regions.RegionModel, 0)
	db := global.Orm.Debug().Table("lc_tencent_regions")
	if parent > 0 {
		db.Where("parent_id = ?", parent)
	}
	db.Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

// 获取省、市、县
func (d *PlaceDao) GetRegionsListById(id int) *dingo.ErrorWrap {
	m := &regions.RegionModel{}
	db := global.Orm.Debug().Table("lc_tencent_regions")
	if id > 0 {
		db.Where("id = ?", id)
	}
	db.Find(m)
	return dingo.ErrorIf(db.Error, m)
}

func (d *PlaceDao) GetPlaceListByEntryStatus(status int8) *dingo.ErrorWrap {
	var lists []placeresp.PlaceToEntry
	db := global.Orm.Table("places").Where("entry_status = ?", status).Find(&lists)
	return dingo.ErrorIf(db.Error, lists)
}

func (d *PlaceDao) UpdatePlaceEntryStatusById(m *placemodel.PlaceModel) *dingo.ErrorWrap {
	db := global.Orm.Table("places").Model(&m).
		Select("entry_status", "status").
		Updates(m)
	return dingo.ErrorIf(db.Error, true)
}

func (d *PlaceDao) GetPlaceNameIsRepeat(placeName string) (*dingo.ErrorWrap, int64) {
	m := placemodel.NewPlaceModel()
	db := global.Orm.Debug().Table("places").Where("place_name = ?", placeName).Find(&m)
	return dingo.ErrorIf(db.Error, m), db.RowsAffected
}

func (d *PlaceDao) GetPlaceArr() *dingo.ErrorWrap {
	var lst []placemodel.PlaceModel
	db := global.Orm.Debug().Table("places").Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

func (d *PlaceDao) GetPlaceTestArr(placeIds []int) *dingo.ErrorWrap {
	var lst []placemodel.PlaceModel
	db := global.Orm.Debug().Table("places").Where("id in (?)", placeIds).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

func (d *PlaceDao) UpdatePlaceId(m *placemodel.PlaceModel) *dingo.ErrorWrap {
	db := global.Orm.Table("places").Model(&m).
		Select("province_id", "city_id", "county_id").
		Where("id=?", m.Id).
		Updates(m)
	return dingo.ErrorIf(db.Error, true)
}

//查询网点收益
func (d *PlaceDao) GetPlaceDividends(userId int, placeIds []int) *dingo.ErrorWrap {

	var placeDividends []placeresp.PlaceDividendsModel
	sql := `SELECT sum( IF( state = 5, money, 0 )) place_money,place_id,user_id FROM dividends_log WHERE place_id in(?) AND user_id in(?) GROUP BY place_id,user_id `
	db := global.Orm.Debug().Raw(sql, placeIds, userId).Find(&placeDividends)
	return dingo.ErrorIf(db.Error, placeDividends)
}
func (d *PlaceDao) GetPlacesMoney(isAdmin, isDraw uint8, placeIds []int) *dingo.ErrorWrap {
	var incomeModel []*placeresp.PlaceMoneyPlaceIdsModel

	//if isAdmin == 2 {
	//	incomeSql := "SELECT SUM(money) as place_money,place_id FROM orders Where 1= 1 AND place_id in (?) AND PERIOD_DIFF( date_format( now( ), '%Y%m' ), date_format( DATE_FORMAT(FROM_UNIXTIME(end_at),'%Y-%m-%d'), '%Y%m' ) ) = 1  GROUP BY place_id"
	//	db := global.Orm.Debug().Raw(incomeSql, placeIds).Find(&incomeModel)
	//	return dingo.ErrorIf(db.Error, incomeModel)
	//}

	//if isDraw == 1 {
	//	incomeSql := "SELECT SUM(money) as place_money,place_id FROM orders Where 1= 1 AND place_id in (?) AND PERIOD_DIFF( date_format( now( ), '%Y%m' ), date_format( DATE_FORMAT(FROM_UNIXTIME(end_at),'%Y-%m-%d'), '%Y%m' ) ) = 1  and is_tianhai = 0 GROUP BY place_id"
	//	db := global.Orm.Debug().Raw(incomeSql, placeIds).Find(&incomeModel)
	//	return dingo.ErrorIf(db.Error, incomeModel)
	//} else {
	incomeSql := "SELECT SUM(money) as place_money,place_id FROM orders Where 1= 1 AND place_id in (?) and is_draw = 0 and is_tianhai = 0 and state = 5 AND PERIOD_DIFF( date_format( now( ), '%Y%m' ), date_format( DATE_FORMAT(FROM_UNIXTIME(end_at),'%Y-%m-%d'), '%Y%m' ) ) = 1  GROUP BY place_id"
	db := global.Orm.Debug().Raw(incomeSql, placeIds).Find(&incomeModel)
	return dingo.ErrorIf(db.Error, incomeModel)
	//}

}

func (d *PlaceDao) GetPlaceDividendsByDate(userIds, placeIds []int, date string) *dingo.ErrorWrap {
	var placeDividends []placeresp.PlaceDividendsModel
	sql := `SELECT sum( IF( state = 5, money, 0 )) place_money,place_id,user_id,DATE_FORMAT(FROM_UNIXTIME(create_at),'%Y-%m-%d') as date FROM dividends_log WHERE place_id in(?) AND user_id in(?) AND DATE_FORMAT(FROM_UNIXTIME(create_at),'%Y-%m-%d') = ?  GROUP BY place_id,user_id,date `
	db := global.Orm.Debug().Raw(sql, placeIds, userIds, date).Find(&placeDividends)
	return dingo.ErrorIf(db.Error, placeDividends)
}

//func (d *PlaceDao) GetPlaceExportList(param *request.PlacesListReq, loginUserId int, isAdmin uint8, isPlace uint8) *dingo.ErrorWrap {
//
//	var (
//		lst    []*placeresp.PlaceExportModel
//		count  int64
//		limit  int = param.PageSize
//		offset int = param.PageSize * (param.PageNo - 1)
//	)
//
//	db := global.Orm.Debug().Table("places p").
//		Select("p.id,p.level,p.place_name as name,u.name as user_name,p.user_id,u.phone,u.profit_proportion,ku.user_name as branch_user_name,p.hotel_id,p.province,p.city,p.create_at,p.status,?", gorm.Expr("concat(parent.user_name,'-',parent.name) parent_name")).
//		Joins("left join users u on p.user_id = u.id").
//		Joins("left join users ku on p.branch_user_id = ku.id").
//		Joins("left join users parent on u.parent_id = parent.id")
//
//	if param.PlaceName != "" { //网点名称
//		db.Where("p.place_name like ?", fmt.Sprint("%", param.PlaceName, "%"))
//	}
//	if param.Status > 0 { // 查询条件：状态
//		db.Where("p.status = ?", param.Status)
//	}
//	if param.AreaCode != "" { //地区全称
//		db.Where("p.area_code in (?)", param.AreaCode)
//	}
//	if param.AgentUserId > 0 {
//		userIdArr := NewUserDao().QueryChildUserIds(param.AgentUserId).Unwrap().([]int)
//		db.Where("u.id in (?)", userIdArr)
//
//	}
//	if param.BranchUserId > 0 {
//
//		userIdArr := NewUserDao().QueryChildUserIds(param.BranchUserId).Unwrap().([]int)
//		placeIdArr := NewPlaceDao().GetPlaceByIds(userIdArr).Unwrap().([]int)
//		placesBranchIds := NewUserDao().GetPlacesId(param.BranchUserId).Unwrap().([]int)
//		//合并网点
//		placesBranchIds = append(placesBranchIds, placeIdArr...)
//
//		//去重网点
//		placeIdArr = utils.RemoveRepByMap(placesBranchIds)
//
//		db.Where("p.id in (?)", placeIdArr)
//	}
//	if param.Name != "" {
//		db.Where("u.name = ?", param.Name)
//	}
//	if param.Phone != "" {
//		db.Where("u.phone = ?", param.Phone)
//	}
//
//	if param.ProvinceId > 0 {
//		db.Where("p.province_id = ?", param.ProvinceId)
//	}
//
//	if param.CityId > 0 {
//		db.Where("p.city_id = ?", param.CityId)
//	}
//
//	if param.CountyId > 0 {
//		db.Where("p.county_id = ?", param.CountyId)
//	}
//
//	if param.IsTianHai > 0 {
//		db.Where("p.is_tianhai = ?", param.IsTianHai)
//	}
//
//	if param.ProjectLabel != "" { db.Where("p.project_label = ?", param.ProjectLabel) } // 按项目搜索
//
//	// 如果是运营商或代理商登录，只展示旗下所有商户
//	//if isAdmin == 3 && isPlace != 3 {
//	//
//	//	userIdArr := NewUserDao().QueryChildUserIds(loginUserId).Unwrap().([]int)
//	//	db.Where("u.id in (?)", userIdArr)
//	//	//db.Where("u.parent_id = ? ", loginUserId)
//	//}
//	if isAdmin > helper.TypeNumIsAdminAgent && isAdmin != helper.TypeNumIsAdminBranch {
//
//		userIdArr := NewUserDao().QueryChildUserIds(loginUserId).Unwrap().([]int)
//		placeIdArr := NewPlaceDao().GetPlaceByIds(userIdArr).Unwrap().([]int)
//		db.Where("p.id in (?)", placeIdArr)
//		//db.Where("u.parent_id = ? ", loginUserId)
//	}
//
//	if isAdmin == helper.TypeNumIsAdminBranch {
//		userIdArr := NewUserDao().QueryChildUserIds(loginUserId).Unwrap().([]int)
//		placeIdArr := NewPlaceDao().GetPlaceByIds(userIdArr).Unwrap().([]int)
//		//分公司获取关联的网点Id
//		placesBranchIds := NewUserDao().GetPlacesId(loginUserId).Unwrap().([]int)
//
//		//合并网点
//		placeIdArr = append(placeIdArr, placesBranchIds...)
//
//		//去重网点
//		placeIdArr = utils.RemoveRepByMap(placeIdArr)
//
//		db.Where("p.id in (?)", placeIdArr)
//	}
//
//	// 创建时间查询
//	if param.BeginTime != "" {
//		beginTime := strings.Split(param.BeginTime, ",")
//		db.Where("DATE_FORMAT(FROM_UNIXTIME(p.create_at),'%Y-%m-%d') >=  DATE_FORMAT(FROM_UNIXTIME(?),'%Y-%m-%d') and "+
//			"DATE_FORMAT(FROM_UNIXTIME(p.create_at),'%Y-%m-%d')<=  DATE_FORMAT(FROM_UNIXTIME(?),'%Y-%m-%d')", beginTime[0], beginTime[1])
//	}
//
//	//分公司网点
//	//if isPlace == helper.TypeNumIsPlaceKa {
//	//	placesIdArr := NewUserDao().GetPlacesId(loginUserId).Unwrap().([]int)
//	//	userIdArr := NewUserDao().QueryChildUserIds(loginUserId).Unwrap().([]int)
//	//	db.Where("(p.id in (?) or u.id in (?))", placesIdArr, userIdArr)
//	//}
//	if isAdmin == 5 {
//		placesIdArr := NewUserDao().GetPlacesId(loginUserId).Unwrap().([]int)
//		userIdArr := NewUserDao().QueryChildUserIds(loginUserId).Unwrap().([]int)
//		db.Where("(p.id in (?) or u.id in (?))", placesIdArr, userIdArr)
//	}
//
//	db.Order("p.used_rate,p.create_at desc")
//
//	db.Limit(limit).Offset(offset).Find(&lst).Limit(-1).Offset(-1).Count(&count)
//
//	return dingo.ErrorIf(db.Error, lst, count)
//}

func (d *PlaceDao) GetPlaceMoneyList(placeIds []int, isDraw uint8) *dingo.ErrorWrap {
	var placeMoneyPlaceIds []placeresp.PlaceMoneyPlaceIdsModel
	sql := ""
	if isDraw != 1 {
		sql = `SELECT SUM(o.settlement_money) as place_money,o.place_id FROM orders o  WHERE o.is_draw = 0 and o.place_id in (?)  and o.state = 5  AND o.is_tianhai = 0 GROUP BY o.place_id`

	} else {
		sql = `SELECT SUM(o.settlement_money) as place_money,o.place_id FROM orders o  WHERE o.place_id in (?)  and o.state = 5  AND o.is_tianhai = 0 GROUP BY o.place_id`
	}

	db := global.Orm.Debug().Raw(sql, placeIds).Find(&placeMoneyPlaceIds)
	return dingo.ErrorIf(db.Error, placeMoneyPlaceIds)
}

func (d *PlaceDao) GetPlaceIds() *dingo.ErrorWrap {
	var ids []int
	sql := "SELECT place_id FROM devices WHERE prod_type IN (1,2,3) and place_id > 0 GROUP BY place_id"
	db := global.Orm.Raw(sql).Find(&ids)
	return dingo.ErrorIf(db.Error, ids)
	//db := global.Orm.Debug().Select("id").Table("places").Find(&ids)
	//return dingo.ErrorIf(db.Error, ids)
}

//查询网点首单时间
func (d *PlaceDao) GetPlaceFirstOrderTime(placeIds []int) *dingo.ErrorWrap {
	var placeFirstOrderTime []placeresp.PlaceFirstOrderTime
	sql := `SELECT DATE_FORMAT( FROM_UNIXTIME( create_at ), '%Y-%m-%d' ) as firs_date,place_id FROM orders  WHERE place_id in(?)  GROUP BY place_id ORDER BY firs_date asc`
	db := global.Orm.Debug().Raw(sql, placeIds).Find(&placeFirstOrderTime)
	return dingo.ErrorIf(db.Error, placeFirstOrderTime)
}

//查询网点是否登录
func (d *PlaceDao) GetPlaceUserIsLogin(userId int) *dingo.ErrorWrap {
	var loginCount int64
	db := global.Orm.Debug().Table("login_logs").
		Where("user_id = ? AND `desc`=? AND FROM_UNIXTIME(create_at)>'2021-07-01'", userId, "登录成功").Count(&loginCount)
	return dingo.ErrorIf(db.Error, loginCount)
}

//查询获取携程母酒店ID
func (d *PlaceDao) GetPlaceHotelId(placeIds []int) *dingo.ErrorWrap {

	var m []placeresp.PlaceHotelIdExport
	db := global.Orm.Table("places").Select("id,hotel_id").Where("id in (?)", placeIds).Find(&m)
	return dingo.ErrorIf(db.Error, m)
}

func (d *PlaceDao) GetPlaceDeviceCount() *dingo.ErrorWrap {
	var deviceCountPlaceIds []placeresp.DeviceCountPlaceIdsModel
	sql := `SELECT count(id) as total,place_id FROM devices  GROUP BY place_id`
	db := global.Orm.Debug().Raw(sql).Find(&deviceCountPlaceIds)
	return dingo.ErrorIf(db.Error, deviceCountPlaceIds)
}

//  验证相同网点名称，排除自己
func (d *PlaceDao) GetPlaceByName(placeName string, placeId int) *dingo.ErrorWrap {
	m := placemodel.NewPlaceModel()
	db := global.Orm.Table("places").Where("place_name = ? and id <> ?", placeName, placeId).Find(m)
	return dingo.ErrorIf(db.Error, m)
}

//查询门店公告
func (d *PlaceDao) GetPlaceBulletinById(id int) *dingo.ErrorWrap {
	m := &placemodel.PlaceModel{}
	sql := "select bulletin from places  WHERE id = ? and is_bulletin = 1"
	db := global.Orm.Debug().Raw(sql, id).Find(&m)
	return dingo.ErrorIf(db.Error, m)
}

// 查询最近七天未产生订单的商户
func (d *PlaceDao) GetPlaceRecentlyOrder(date string) *dingo.ErrorWrap {
	var m []placeresp.PlaceRankList
	selectStr := "p.id,p.place_name, count(o.id) total,p.device_count "
	db := global.Orm.Table("places p").Select(selectStr)
	db.Joins("LEFT JOIN orders o ON o.place_id = p.id and DATE_FORMAT( FROM_UNIXTIME( o.end_at ), '%Y-%m-%d' ) <= DATE_SUB( CURDATE( ), INTERVAL " + date + " DAY )")
	db.Where("o.id IS  NULL")
	db.Group("p.id")
	db.Find(&m)
	return dingo.ErrorIf(db.Error, m)
}

// 更新门店公告
func (d *PlaceDao) UpdatePlaceAnnouncement(m *placeresp.PlaceBulletin) *dingo.ErrorWrap {
	db := global.Orm.Table("places").Select("bulletin,is_bulletin").Model(&m).Updates(&m)
	return dingo.ErrorIf(db.Error)
}

// 更新直营状态
func (d *PlaceDao) UpdatePlaceIsBusiness(isBusiness int, projectLabel string, branchUserId int) *dingo.ErrorWrap {
	sql := "UPDATE places SET is_business = ? " +
		"WHERE is_steward = 2 and project_label = ? and branch_user_id = ?"
	db := global.Orm.Exec(sql, isBusiness, projectLabel, branchUserId)
	return dingo.ErrorIf(db.Error, true)
}

func (d *PlaceDao) UpdatePlaceIsAdBanner(isAdBanner int, placeId int) *dingo.ErrorWrap {
	sql := "UPDATE places SET is_ad_banner = ? WHERE id = ?"
	db := global.Orm.Exec(sql, isAdBanner, placeId)
	return dingo.ErrorIf(db.Error, true)
}

// 获取用户下的门店ID
func (d *PlaceDao) GetPlaceIdsByUserId(loginUserId int) *dingo.ErrorWrap {
	var ids []int
	db := global.Orm.Debug().Table("places").Select("id")
	//db.Where("is_steward != 1")
	//db.Where("is_business = 2")
	//db.Where("project_label = ''")
	db.Where("DATE_FORMAT( FROM_UNIXTIME( create_at ), '%Y-%m-%d' ) >= '2022-05-01'")

	placesBranchIds := NewUserDao().GetPlacesId(loginUserId).Unwrap().([]int) // 查询用户ID下的所有关联门店
	userIdArr := NewUserDao().QueryChildUserIds(loginUserId).Unwrap().([]int) // 查询用户ID下所有下级用户ID
	placeIdArr := NewPlaceDao().GetPlaceByIds(userIdArr).Unwrap().([]int)     // 下级用户ID 下的门店
	placesBranchIds = append(placesBranchIds, placeIdArr...)                  // 合并门店
	placesIds := utils.RemoveRepByMap(placesBranchIds)                        // 去重门店
	db.Where("id in (?)", placesIds)

	db.Find(&ids)
	return dingo.ErrorIf(db.Error, ids)
}

func (d *PlaceDao) GetLastPlaceInfo() *dingo.ErrorWrap {
	m := placemodel.NewPlaceModel()
	db := global.Orm.Debug().Table("places").Order("id desc").Limit(1).Find(&m)
	return dingo.ErrorIf(db.Error, m)
}
